package com.example.matrixdemo;

import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Shader;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

import androidx.annotation.Nullable;

/**
 * @ProjectName: MatrixDemo
 * @Package: com.example.matrixdemo
 * @ClassName: MatrixView
 * @Description: java类作用描述
 * @Author: 作者名
 * @CreateDate: 2021/8/19 10:58
 * @UpdateUser: 更新者：
 * @UpdateDate: 2021/8/19 10:58
 * @UpdateRemark: 更新说明：
 * @Version: 1.0
 */
public class MatrixView extends View {

    private Matrix mMatrix;
    private Bitmap mBitmap;
    private Paint mPaint,mPaintMask,mPaintShadow;
    private int mSliceDistance;//切片距离
    private int mSliceCount = 6;//切片数量
    private LinearGradient mLinearGradient;//渐变阴影
    private float mScaleX = 1f;//X轴的缩放比例
    private float mStartX;//用于记录开始触摸时的X轴的位置
    private float mSkewYRate = 0.4f;//Y轴的偏移比率
    private int mShadow = 250;//阴影透明度的最大值
    private ValueAnimator mValueAnimator;

    public MatrixView(Context context) {
        this(context,null);
    }

    public MatrixView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs,0);
    }

    public MatrixView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
        mMatrix = new Matrix();
        mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_bg);
        mPaint  = new Paint(Paint.ANTI_ALIAS_FLAG);
        mSliceDistance = mBitmap.getWidth() / mSliceCount;

        mPaintMask = new Paint(Paint.ANTI_ALIAS_FLAG);
        mPaintShadow = new Paint(Paint.ANTI_ALIAS_FLAG);
    }

    /**
     * 设置横向的缩放
     * @param mScaleX
     */
    public void setScaleX(float mScaleX) {
        this.mScaleX = mScaleX;
        invalidate();
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()){
            case MotionEvent.ACTION_DOWN:
                mStartX = event.getX();
                break;
            case MotionEvent.ACTION_MOVE:
                //计算滑动的距离
                float moveDistance = event.getX() - mStartX;
                mStartX = event.getX();
                //缩放的偏移量
                if(moveDistance > 0){
                    //向右滑动（放大）
                    mScaleX = mScaleX + Math.abs(moveDistance) / getWidth();
                }else {
                    //向左滑动（缩小）
                    mScaleX = mScaleX - Math.abs(moveDistance) / getWidth();
                }
                //限定边界值
                if(mScaleX < 0){
                    mScaleX = 0f;
                }else if(mScaleX > 1){
                    mScaleX = 1;
                }
                invalidate();
                break;
            case MotionEvent.ACTION_UP:
                //手指抬起自动展开或折叠
                startAnim();
                break;
        }
        return true;
    }

    /**
     * 开始展开或折叠的动画
     */
    private void startAnim() {
        if(mValueAnimator != null && mValueAnimator.isRunning()){
            mValueAnimator.cancel();
        }
        mValueAnimator = ValueAnimator.ofFloat(mScaleX, mScaleX > 0.5 ? 1 : 0);
        mValueAnimator.setDuration(500);
        mValueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                float scaleX = (float) animation.getAnimatedValue();
                setScaleX(scaleX);
            }
        });
        mValueAnimator.start();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        Bitmap bitmap1 = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
        Canvas canvas1 = new Canvas();
        canvas1.setBitmap(bitmap1);

        //根据X轴的缩放比例计算阴影（完全展开的时候没有阴影，随着折叠的时候阴影增加）
        int alpha = (int) ((1 - mScaleX) * mShadow);
        mPaintMask.setColor(Color.argb(alpha,0,0,0));
        mLinearGradient = new LinearGradient(0, 0, mSliceDistance, 0, Color.argb(alpha, 0, 0, 0), Color.TRANSPARENT, Shader.TileMode.CLAMP);
        mPaintShadow.setShader(mLinearGradient);
        //根据缩放比例计算每个切片的宽度
        mSliceDistance = (int) (mBitmap.getWidth() / mSliceCount * mScaleX);
        //根据X轴的缩放比例进行计算Y轴的偏移率（当X轴的缩放比例是1的时候没有错切）
        float skewYRate = mSkewYRate * (1 - mScaleX);
        //缩放的Bitmap的宽度
        int scaleBitmapWidth = (int) (mBitmap.getWidth() * mScaleX);
        //当计算的缩放Bitmap的宽度大于1的时候才进行绘制（否则会出现错误）
        if(scaleBitmapWidth > 1){
            //每次都复原Bitmap
            Bitmap bitmap = Bitmap.createScaledBitmap(mBitmap, scaleBitmapWidth,mBitmap.getHeight(),true);
            for (int i = 0; i < mSliceCount; i++) {
                //每次都重置Matrix
                mMatrix.reset();
                canvas.save();
                float symbol = -1;
                //奇数正偶数负
                if(i % 2 == 0){
                    symbol = 1;
                }
                mMatrix.preTranslate(mSliceDistance * i,0);
                //矩阵设置偏移
                mMatrix.preSkew(0,symbol * skewYRate);
                canvas.setMatrix(mMatrix);
                if(i != 0){
                    //裁剪Bitmap
                    bitmap = Bitmap.createBitmap(bitmap,mSliceDistance,0,bitmap.getWidth() - mSliceDistance,bitmap.getHeight());
                }
                //当切片的索引为奇数时（索引从0开始），切片是向上偏移的因此需要向下偏移一点才能显示完全
                float offsetY = 0;
                if(symbol < 0){
                    offsetY = symbol * skewYRate * (float) bitmap.getWidth() / 6f * mScaleX;
                }
                canvas.clipRect(new RectF(0,0,mSliceDistance,getHeight()));
                canvas.drawBitmap(bitmap,0,-offsetY,mPaint);
                canvas.drawRect(0 ,-offsetY,mSliceDistance,bitmap.getHeight()-offsetY,symbol > 0 ? mPaintMask:mPaintShadow);
                canvas.restore();
            }
            bitmap.recycle();
        }
        //下面是不用规律直接挨个裁剪绘制的代码
//        mMatrix.reset();
//        canvas.save();
//        mMatrix.setSkew(0,0.2f);
//        canvas.setMatrix(mMatrix);
//        canvas.clipRect(new RectF(mSliceDistance * 0,0.2f * (float) bitmap.getHeight() / 6f * 0,mSliceDistance * 1,getHeight()));
//        canvas.drawBitmap(bitmap,mSliceDistance * 0,0.2f * (float) bitmap.getHeight() / 6f * 0,mPaint);
//        canvas.restore();
//        mMatrix.reset();
//        canvas.save();
//        mMatrix.setSkew(0,-0.2f);
//        canvas.setMatrix(mMatrix);
//        bitmap = Bitmap.createBitmap(bitmap,mSliceDistance,0,bitmap.getWidth() - mSliceDistance,bitmap.getHeight());
//        canvas.clipRect(new RectF(mSliceDistance * 1,0.2f * (float) bitmap.getHeight() / 6f * 2,mSliceDistance * 2,getHeight()));
//        canvas.drawBitmap(bitmap,mSliceDistance * 1,0.2f * (float) bitmap.getHeight() / 6f * 2,mPaint);
//        canvas.restore();
//
//        mMatrix.reset();
//        canvas.save();
//        mMatrix.setSkew(0,0.2f);
//        canvas.setMatrix(mMatrix);
//        bitmap = Bitmap.createBitmap(bitmap,mSliceDistance,0,bitmap.getWidth() - mSliceDistance,bitmap.getHeight());
//        canvas.clipRect(new RectF(mSliceDistance * 2,-0.2f * (float) bitmap.getHeight() / 6f * 2,mSliceDistance * 3,getHeight()));
//        canvas.drawBitmap(bitmap,mSliceDistance * 2,-0.2f * (float) bitmap.getHeight() / 6f * 2,mPaint);
//        canvas.restore();
//
//        mMatrix.reset();
//        canvas.save();
//        mMatrix.setSkew(0,-0.2f);
//        canvas.setMatrix(mMatrix);
//        bitmap = Bitmap.createBitmap(bitmap,mSliceDistance,0,bitmap.getWidth() - mSliceDistance,bitmap.getHeight());
//        canvas.clipRect(new RectF(mSliceDistance * 3,0.2f * (float) bitmap.getHeight() / 6f * 4,mSliceDistance * 4,getHeight()));
//        canvas.drawBitmap(bitmap,mSliceDistance * 3,0.2f * (float) bitmap.getHeight() / 6f * 4,mPaint);
//        canvas.restore();
//
//        mMatrix.reset();
//        canvas.save();
//        mMatrix.setSkew(0,0.2f);
//        canvas.setMatrix(mMatrix);
//        bitmap = Bitmap.createBitmap(bitmap,mSliceDistance,0,bitmap.getWidth() - mSliceDistance,bitmap.getHeight());
//        canvas.clipRect(new RectF(mSliceDistance * 4,-0.2f * (float) bitmap.getHeight() / 6f * 4,mSliceDistance * 5,getHeight()));
//        canvas.drawBitmap(bitmap,mSliceDistance * 4,-0.2f * (float) bitmap.getHeight() / 6f * 4,mPaint);
//        canvas.restore();
//
//        mMatrix.reset();
//        canvas.save();
//        mMatrix.setSkew(0,-0.2f);
//        canvas.setMatrix(mMatrix);
//        bitmap = Bitmap.createBitmap(bitmap,mSliceDistance,0,bitmap.getWidth() - mSliceDistance,bitmap.getHeight());
//        canvas.clipRect(new RectF(mSliceDistance * 5,0.2f * (float) bitmap.getHeight() / 6f * 6,mSliceDistance * 6,getHeight()));
//        canvas.drawBitmap(bitmap,mSliceDistance * 5,0.2f * (float) bitmap.getHeight() / 6f * 6,mPaint);
//        canvas.restore();
        super.onDraw(canvas);
    }
}
